﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using NetBay.Core.BusinessEntities.Enum;
using NetBay.Core.BusinessEntities.Barcodes;
using System.ServiceModel.DomainServices.Server;
using System.ComponentModel.DataAnnotations;


namespace NetBay.Core.BusinessEntities
{

    /// <summary>
    /// m_szName (string) : file name
    /// m_bmImg  (Bitmap) : Image's file
    /// </summary>
    [DataContract(Namespace="NetBay.Core.BusinessEntities")]
    public class ImageRio : ReturnObject
    {
        private List<BarcodeResultItem> m_oOriginalBarcode = new List<BarcodeResultItem>();
        private List<BarcodeSeparator> m_oSeparatorBarcode = new List<BarcodeSeparator>();
        private string m_szName;
        /// <summary>
        /// Represent the name of the image or the directory
        /// </summary>
        [DataMember]
        public string Name
        {
            get { return m_szName; }
            set { m_szName = value; }
        }

        private byte[] m_bmImg;
        /// <summary>
        /// Represent the image data
        /// </summary>
        [DataMember]
        public byte[] Img
        {
            get { return m_bmImg; }
            set { m_bmImg = value; }
        }

        private long m_iImageSize;
        /// <summary>
        /// Represent the image size or directory size
        /// </summary>
        [DataMember]
        public long ImageSize
        {
            get { return m_iImageSize; }
            set { m_iImageSize = value; }
        }

        private string m_szFullPath;
        /// <summary>
        /// Represent the full path of the image or directory
        /// </summary>
        [DataMember]
        public string FullPath
        {
            get { return m_szFullPath; }
            set { m_szFullPath = value; }
        }

        private int m_iNumberPages;
        /// <summary>
        /// Represent the number of pages
        /// </summary>
        [DataMember]
        public int NumberPages
        {
            get { return m_iNumberPages; }
            set { m_iNumberPages = value; }
        }

        private List<ImageRio> m_oFileList;
        /// <summary>
        /// Get or Set the Image List inside the directory
        /// </summary>
        [DataMember]
        public List<ImageRio> FileList
        {
            get { return m_oFileList; }
            set { m_oFileList = value; }
        }

        private string m_RootDirectoryName;
        /// <summary>
        /// Get or set the name of the root directory
        /// </summary>
        [DataMember]
        public string RootDirectoryName
        {
            get { return m_RootDirectoryName; }
            set { m_RootDirectoryName = value; }
        }

        private ImageRioType m_oImageType;
        /// <summary>
        /// Get or Set the type of Image (Unknown, ImageFile, Directory, ...)
        /// </summary>
        [DataMember]
        public ImageRioType ImageType
        {
            get { return m_oImageType; }
            set { m_oImageType = value; }
        }

        private bool m_bIsDirectory;
        /// <summary>
        /// Get 
        /// </summary>
        [DataMember]
        public bool isDirectory
        {
            get
            {
                if (ImageType == ImageRioType.ImageFile)
                {
                    m_bIsDirectory = false;
                }
                else
                {
                    //if (Directory.Exists(this.FullPath))
                    m_bIsDirectory = true;
                }
                return m_bIsDirectory;
            }
            set
            {
                m_bIsDirectory = false;
            }
        }

        private bool m_bisInsideDirectory;
        /// <summary>
        /// Get or set a value that indicate if the image is inside a directory
        /// </summary>
        [DataMember]
        public bool isInsideDirectory
        {
            get
            {
                if (string.IsNullOrEmpty(RootDirectoryName))
                {
                    m_bisInsideDirectory = false;
                }
                else
                {
                    m_bisInsideDirectory = true;
                }
                return m_bisInsideDirectory;
            }
            set
            {
                m_bisInsideDirectory = false;
            }
        }

        [DataMember]
        public String Author { get; set; }

        [DataMember]
        public DateTime CreationDate { get; set; }

        [DataMember]
        public DateTime LastModificationDate { get; set; }

        [DataMember]
        public String LastModificationAuthor { get; set; }

        [DataMember]
        public String Dimension { get; set; }

        [DataMember]
        public String Resolution { get; set; }

        /// <summary>Barcode Error on the document.</summary>
        [DataMember]
        public Boolean BarCodePageError { get; set; }

        /// <summary>
        /// Gets or sets the original barcodes.
        /// </summary>
        /// <value>The original barcodes.</value>
        [Association("FK_Barcodes", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<BarcodeResultItem> OriginalBarcodes
        {
            get { return m_oOriginalBarcode; }
            set
            {
                if (value != null)
                {
                    m_oOriginalBarcode = value;
                    ItemEntity.SetForeignKey(m_oOriginalBarcode, Key);
                }
            }
        }

        /// <summary>
        /// Gets or sets the rio barcodes.
        /// </summary>
        /// <value>The rio barcodes.</value>
        [Association("FK_RioBarcodes", "Key", "ForeignKey")]
        [Include]
        [DataMember]
        public List<BarcodeSeparator> SeparatorBarcodes
        {
            get { return m_oSeparatorBarcode; }
            set
            {
                if (value != null)
                {
                    m_oSeparatorBarcode = value;
                    ItemEntity.SetForeignKey(m_oSeparatorBarcode, Key);
                }
            }
        }
                
        #region Functions

        /// <summary>
        /// Check if the specified directory is a valid RioDirectory
        /// </summary>
        /// <param name="p_sDirectoryName"></param>
        /// <returns></returns>
        public static bool isValidDirectoryName(string p_sDirectoryName)
        {
            bool returnValue = false;
            try 
	        {
                ImageRioType imgType;
                string sPrefix = p_sDirectoryName.Split('-')[0];
                returnValue = System.Enum.TryParse<Enum.ImageRioType>(sPrefix.Trim(), out imgType);
	        }
	        catch (Exception)
	        {
                returnValue = false;
	        }
            return returnValue;
        }

        /// <summary>
        /// Convert a directory name to an ImageRioType
        /// </summary>
        /// <param name="p_sDirectoryName"></param>
        /// <returns></returns>
        public static ImageRioType ConvertDirectoryNameToImageRioType(string p_sDirectoryName)
        {
            ImageRioType imgType= ImageRioType.Unknown;
            if (isValidDirectoryName(p_sDirectoryName))
            {
                string sPrefix = p_sDirectoryName.Split('-')[0];
                System.Enum.TryParse<Enum.ImageRioType>(sPrefix.Trim(), out imgType);
            }
            return imgType;
        }

        #endregion

        #region Contructors
        public ImageRio()
        {
            m_oImageType = ImageRioType.ImageFile;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Document"/> class for error usages
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <param name="applicationException">The application exception.</param>
        public ImageRio(string errorMessage, Exception applicationException = null)
            : base(errorMessage, applicationException)
        {
            m_oImageType = ImageRioType.ImageFile;
        }

        public ImageRio(string P_szName, byte[] P_bmImg)
        {
            m_szName = P_szName;
            m_bmImg = P_bmImg;
            m_oImageType = ImageRioType.ImageFile;
        }

        public ImageRio(string P_szName, byte[] P_bmImg, long p_iFileSize)
            :this(P_szName, P_bmImg)
        {
            m_iImageSize = p_iFileSize;
            m_oImageType = ImageRioType.ImageFile;
        }

        public ImageRio(string P_szName, byte[] P_bmImg, long p_iFileSize, string p_szFullPath)
            :this(P_szName, P_bmImg, p_iFileSize)
        {
            m_szFullPath = p_szFullPath;
            m_oImageType = ImageRioType.ImageFile;
        }

        public ImageRio(string P_szName, byte[] P_bmImg, long p_iFileSize, string p_szFullPath, int p_iNumberPages)
            : this(P_szName, P_bmImg, p_iFileSize, p_szFullPath)
        {
            m_iNumberPages = p_iNumberPages;
            m_oImageType = ImageRioType.ImageFile;
        }

        #endregion
    }

    public abstract class ImageRioDer : ImageRio
    {
        public ImageRioDer(string P_szName, byte[] P_bmImg, long p_iFileSize, string p_szFullPath)
            : base(P_szName, P_bmImg, p_iFileSize, p_szFullPath)
        {

        }
    }
}
